#include "8259a.h"
#include "io.h"

static void enable_rtc()
{
    // TC寄存器B
    char out_v = 0x0b;
    // 阻断NMI
    out_v |= 0x80;
    out_byte(0x70, out_v);

    // 设置寄存器B，开放周期性中断、更新结束后中断，BCD码，24小时制
    out_byte(0x71, 0x52);

    // CMOS寄存器A
    out_byte(0x70, 0x8a);
    out_byte(0x71, 0x2f);

    // 通过读，清零寄存器C，防止相关位被置位，导致对应的中断不再发生（非必须，稳妥写法）
    out_byte(0x70, 0x0c);

    char v = in_byte(0x71);

    // 读8259从片的IMR寄存器
    v = in_byte(0xa1);
    // 清除bit 0(此位连接RTC)
    v &= 0xfe;
    // 写回去
    out_byte(0xA1, v);
}

void set_8253_frequency()
{
    // 设置PIT的工作模式
    out_byte(0x43, 0x36);
    
    short frequency = 0xD8E6;
    // 发送低字节到通道0
    out_byte(0x40, frequency & 0xff);
    // 发送高字节到通道0
    out_byte(0x40, (frequency >> 8) & 0xff);
}

void init_8259a(void)
{
    // 向主发送ICW1
    out_byte(0x20, 0x11);
    // 向从发送ICW1
    out_byte(0xA0, 0x11);

    // 向主发送ICW2
    out_byte(0x21, 0x20);
    // 向从发送ICW2
    out_byte(0xA1, 0x28);

    // 向主发送ICW3
    out_byte(0x21, 0x04);
    // 向从发送ICW3
    out_byte(0xA1, 0x02);

    // 向主发送ICW4
    out_byte(0x21, 0x03);
    // 向从发送ICW4
    out_byte(0xA1, 0x03);

    // 屏蔽主片所有中断
    char main_irq_mask = 0b11111111;
    out_byte(0x21, main_irq_mask);

    char slave_irq_mask = 0b11111101;
    out_byte(0xA1, slave_irq_mask);

    enable_rtc();

    set_8253_frequency();
}